import 'dart:ffi';

import 'package:dart_native/src/darwin/foundation/collection/nsarray.dart';
import 'package:dart_native/src/darwin/foundation/collection/nsdictionary.dart';
import 'package:dart_native/src/darwin/foundation/collection/nsset.dart';
import 'package:dart_native/src/darwin/foundation/nsstring.dart';

typedef ConvertorFromPointer = dynamic Function(Pointer<Void> ptr);

/// Register a function for converting a Dart object from a [Pointer].
///
/// Some [type]s can be created using the [fromPointer] method.
/// An example for [NSString]:
///
/// ```dart
/// registerTypeConvertor('NSString', (ptr) {
///     return NSString.fromPointer(ptr);
/// });
/// ```
/// The example above can be generated by applying `@native` annotation on Dart
/// wrapper class. See [NSString].
void registerTypeConvertor(String type, ConvertorFromPointer convertor) {
  if (_convertorCache[type] == null) {
    _convertorCache[type] = convertor;
  }
}

/// Returns the [ConvertorFromPointer] function for [type].
ConvertorFromPointer? convertorForType(String type) {
  return _convertorCache[type];
}

/// built-in convertors
///
/// Add custom convertors using [registerTypeConvertor] function.
/// See also: [objcInstanceFromPointer]
Map<String, ConvertorFromPointer> _convertorCache = {
  'String': (ptr) {
    return NSString.fromPointer(ptr).raw;
  },
  'List': (ptr) {
    return NSArray.fromPointer(ptr).raw;
  },
  'Map': (ptr) {
    return NSDictionary.fromPointer(ptr).raw;
  },
  'Set': (ptr) {
    return NSSet.fromPointer(ptr).raw;
  },
};
